home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / a86v400.zip / TCOLS.8 < prev    next >
Text File  |  1994-01-31  |  17KB  |  405 lines

  1. ;---------------
  2. ;   TCOLS
  3. ;---------------
  4.  
  5.   JMP TCOLS
  6.  
  7. DEFAULT MACRO
  8.   DEFT_#1 EQU #2
  9.   DB ' (default #2)',0D,0A
  10. #EM
  11.  
  12. DOC_MSG:
  13.  
  14. DB 0D,0A
  15. DB 'TCOLS V1.1  Copr.1994 Eric Isaacson, 416 E. Univ.St., BMG IN 47401',0D,0A
  16. DB '  Permission to use granted only to registered A86 users.',0D,0A,0D,0A
  17.  
  18.   DB 'TCOLS converts single-column input into paged, multi-column output.',0D,0A
  19.   DB 'Usage: TCOLS <in >out #1 #2 #3 #4 #5          , where',0D,0A
  20.   DB '  #1 is the number of major columns you want each page split into',0D,0A
  21.   DB '  #2 is the number of lines to skip between each page'
  22.   DEFAULT  SKIPCT,6
  23.   DB '  #3 is the number of chars per line the printer is now set to'
  24.   DEFAULT  PWIDTH,80
  25.   DB '  #4 is the number of lines per page the printer is now set to'
  26.   DEFAULT  LPAGE,66
  27.   DB '  #5 is which line within the first page the printer is now at'
  28.   DEFAULT  LSTART,0
  29.   DB          0D,0A
  30.  
  31. DB 'Examples:',0D,0A
  32. DB 'TCOLS <MYPROG.XRF >PRN 4 6 96 88',0D,0A
  33. DB '   sends the file MYPROG.XRF to the printer, split into 4 columns, where'
  34. DB          0D,0A
  35. DB '   the printer is set to 96 characters a line, 8 lines per inch.',0D,0A
  36. DB 'TCOLS <NARROW.LST 6 0 80 23 22 | MORE',0D,0A
  37. DB '   provides 6-column screen-paged output.',0D,0A
  38. DB 'NOTE for readability, TCOLS will convert underscores to hyphens when the'
  39. DB          0D,0A
  40. DB '   lines per page is greater than 80.',0D,0A
  41.  
  42. DOC_LEN EQU $-DOC_MSG
  43.  
  44. DATA SEGMENT
  45. BUF:
  46.          DB 04000 DUP (?)
  47. OUTBUF:
  48.          DB 02000 DUP (?)
  49. OUTBUF_LIM:
  50.          DB 0100 DUP (?)
  51.          DW ?          ; in case the line-overflow logic scans back
  52. SOURCE_BUF:
  53.          DB 04002 DUP (?)
  54.   WIDTH      DW ?   ; number of characters in an major output column
  55.   NCOLS      DB ?   ; number of major output columns on a page
  56.   LPAGE      DB ?   ; total number of lines on a page (including skipped)
  57.   PWIDTH     DW ?   ; total width in characters of a printed page
  58.   BUFEND     DW ?   ; pointer reached when a buffered page is complete
  59.   SKIPCT     DB ?   ; number of lines skipped between pages
  60.   LSTART     DB ?   ; number of first-page lines already output before program
  61.   THISPAGE   DB ?   ; number of printed lines on this page
  62. DATA ENDS
  63.  
  64. MAIN:
  65. TCOLS:
  66.   CALL SCAN_ARGS    ; scan the command arguments
  67.   CALL READ_SOURCE  ; read the first block of source text
  68.   JZ >L2        ; exit if there was no source text
  69. L1:            ; loop here for each page of output
  70.   CALL GATHER_PAGE  ; input a page, and arrange in into columns
  71.   PUSHF         ; save Z-flag, to see if there is more input
  72.   CALL OUTPUT_PAGE  ; process the columns-buffer into final output
  73.   CALL OFLUSH        ; flush the output buffer
  74.   POPF            ; restore Z flag, is there more output?
  75.   JNZ L1        ; loop if there is more output
  76. L2:
  77.   JMP GOOD_EXIT     ; all done, go back to operating system
  78.  
  79.  
  80. ; CHECK_DIGIT sees if there is another command-tail argument pointed to by
  81. ;   SI.  If there is, it had better start with a decimal digit, or else we
  82. ;   abort the program.    We return NZ if there is an argument; Z if there are
  83. ;   no more arguments (terminator 0FF is seen).
  84.  
  85. CHECK_DIGIT:
  86.   PUSH AX        ; preserve register across call
  87. L1:            ; loop here to skip over blanks and control chars
  88.   LODSB         ; load the next character
  89.   CMP AL,' '        ; is it a blank or control char?
  90.   JBE L1        ; loop if yes, to skip the character
  91.   DEC SI        ; retreat SI back to the first argument-char
  92.   CMP AL,0FF        ; is it the command-tail terminator?
  93.   JE >L2        ; return Z if yes
  94.   SUB AL,'0'        ; reduce first character to 0--9 range if digit
  95.   CMP AL,10        ; is the character a digit?
  96.   JAE >E1        ; abort the program if not; NZ is set if yes
  97. L2:
  98.   POP AX        ; restore clobbered register
  99.   RET
  100.  
  101. E1:            ; improper command tail in program invocation
  102.   MOV DX,DOC_MSG    ; point to the documentation-message
  103.   MOV CX,DOC_LEN    ; load size of message
  104.   JMP ERROR_EXIT    ; educate the user about this program
  105.  
  106.  
  107. ; CLEAR_PAGE calculates the number of lines to be printed on the coming
  108. ;   page, at sets up a blank columns-buffer based on that number.  We return
  109. ;   with DI pointing just beyond the blanked buffer.  If the calculations
  110. ;   indicate something is wrong, we abort the program.
  111.  
  112. CLEAR_PAGE:
  113.   MOV AL,LPAGE        ; fetch the total number of lines on a page
  114.   SUB AL,SKIPCT     ; subtract the number of lines that we skip
  115.   JBE E1        ; abort if we skip more lines than there are
  116.   SUB AL,LSTART     ; also subtract any first-page lines already output
  117.   JBE E1        ; abort if that subtraction has exhausted the count
  118.   MOV THISPAGE,AL   ; store as the number of lines on this page
  119.   MOV LSTART,0        ; cancel first-page count for the subsequent pages
  120.   MOV CX,PWIDTH     ; load the number of characters per line
  121.   MUL CL        ; calculate the number of characters in the columns buffer
  122.   XCHG CX,AX        ; swap the count into CX for blanking
  123.   MOV DI,BUF        ; point DI to the start of the columns buffer
  124.   MOV AL,' '        ; we will fill the buffer with blanks
  125.   REP STOSB        ; buffer is filled, DI points beyond the buffer
  126.   RET
  127.  
  128.  
  129. ; SCAN_ARGS scans the decimal arguments in the command tail at DS:080. All the
  130. ;   appropriate page-size variables are set according to these argument values.
  131.  
  132. SCAN_ARGS:
  133.   MOV SI,080        ; point to the command-tail buffer in the PSP
  134.   LODSB         ; load the size of the command tail
  135.   CBW            ; extend the size AL to AX
  136.   XCHG BX,AX        ; swap the size into BX, for indexing
  137.   MOV B[BX+SI],0FF  ; mark the end of the command-tail with terminator 0FF
  138.   CALL CHECK_DIGIT  ; any there any arguments in the command tail?
  139.   JZ E1         ; abort the program if there are not
  140.   CALL SCAN_DECIMAL ; input the first argument-- number of major columns
  141.   MOV NCOLS,AL        ; store it
  142.   XCHG BX,AX        ; also swap NCOLS into BL for later calculations
  143.   MOV AL,DEFT_SKIPCT; load the default number of lines skipped
  144.   CALL SCAN_DECIMAL ; read the next argument if there is any
  145.   MOV SKIPCT,AL     ; store the number of lines to skip between pages
  146.   MOV AL,DEFT_PWIDTH; load the default page width
  147.   CALL SCAN_DECIMAL ; read the next argument if there is any
  148.   MOV CL,AL        ; store in CL for the moment
  149.   DIV BL        ; divide by major columns count, to get chars per column
  150.   SUB CL,AH        ; subtract remainder from page width, insures even multiple
  151.   MOV AH,0        ; zero out the remainder
  152.   MOV WIDTH,AX        ; store the number of characters in an output column
  153.   CMP AL,2        ; this width had better be at least 2 chars
  154.   JB E1         ; abort the program if not
  155.   MOV AL,CL        ; AX is now the characters-per-line
  156.   MOV PWIDTH,AX     ; store the characters-per-line printer is set to
  157.   MOV AX,CX        ; re-fetch the characters-per-line
  158.   ADD AX,BUF        ; calculate beyond-first-line, reached when buffer full
  159.   MOV BUFEND,AX     ; store the value for later use
  160.   MOV AL,DEFT_LPAGE ; load defualt lines-per-page
  161.   CALL SCAN_DECIMAL ; read the next argument, if there is any
  162.   MOV LPAGE,AL        ; store the total number of lines on a printed page
  163.   MOV AL,DEFT_LSTART; load the default first-line-position
  164.   CALL SCAN_DECIMAL ; read the next argument, if any
  165.   MOV LSTART,AL     ; store the starting first-page position
  166.   RET
  167.  
  168.  
  169. ; GATHER_PAGE takes input text at DS:SI, and formats it into columns on a
  170. ;   single page, at BUF.  RZ if the input file end (0FFH marker) was seen.
  171.  
  172. GATHER_PAGE:
  173.   CALL CLEAR_PAGE   ; blank-fill the columns-buffer
  174.   MOV BX,DI        ; point BX beyond the columns-buffer
  175.   MOV BP,DX,DI,BUF  ; start BP=column ptr  DX=line ptr    DI=char ptr
  176. L1:            ; loop here for each column entry
  177.   CALL GATHER_LINE  ; copy an input line to a column entry
  178.   JZ RET        ; return if there is no more input
  179.   CALL NEXT_LINE    ; advance pointers to the next column entry
  180.   JB L1         ; loop if there is another entry on this page
  181.   OR AL,0FF        ; page complete: set NZ to signal more input
  182.   RET
  183.  
  184.  
  185. ; NEXT_LINE sets DI to the next line of this column in the page display buffer.
  186. ;   It moves to the top of the next column as necessary.  RAE if the page is
  187. ;   full.
  188.  
  189. NEXT_LINE:
  190.   ADD DX,PWIDTH     ; advance column-poi